package systems.rpgBuilder;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;


public class RpgBuilder {
  private static File configFile = null;
  private static Document docXML;
  private static Element root;
  private static SAXBuilder saxBuilder;
  private static List<Faction> factionsList = new ArrayList<Faction>();
  private static List<Classe> classesList = new ArrayList<Classe>();
  private static List<Item> itemsList = new ArrayList<Item>();
  private static String itemRootMultiLangueName;
  private static RpgBuilder instance = new RpgBuilder();
  private static int minLevel;
  private static int maxLevel;
  private RpgBuilder()
  {
    String path = "./config/gameClasses.xml";
    configFile = new File(path);
    loadXML(configFile);
    RpgBuilder.root = RpgBuilder.docXML.getRootElement();
    buildLevels();
    buildFactions();
    buildClasses();
    buildItems();
  }

  private static void loadXML(File xmlFile)
  {
    RpgBuilder.saxBuilder = new SAXBuilder(true);
    try{
      RpgBuilder.docXML = RpgBuilder.saxBuilder.build(xmlFile);
    }catch(JDOMException e){
      System.out.println("The following file does not respect the DTD : "+xmlFile);
      e.printStackTrace();
    } catch (IOException e) {
      System.out.println("Input/Output exception with the following file : "+xmlFile);
      e.printStackTrace();
    }
  }

  private static void buildLevels()
  {
    minLevel = Integer.valueOf(root.getChildText("minLvl"));
    maxLevel = Integer.valueOf(root.getChildText("maxLvl"));
  }
  
  private static void buildFactions()
  {
    Element factionsRoot = root.getChild("factions");
    List<Element> factions = factionsRoot.getChildren();
    
    for(Element faction : factions)
      factionsList.add(new Faction(faction));
  }
  
  private static void buildClasses()
  {
    Element classesRoot = root.getChild("classes");
    List<Element> classes = classesRoot.getChildren();
    
    for(Element classe : classes)
      classesList.add(new Classe(classe));
  }
 
  private static void buildItems()
  {
    Element itemsRoot = root.getChild("items");
    RpgBuilder.itemRootMultiLangueName = itemsRoot.getAttributeValue("rootMultiLangueName");
    List<Element> items = itemsRoot.getChildren();
    
    for(Element item : items)
      itemsList.add(new Item(item));
  }
  
  public static List<Classe> getClassesList()
  {
    return RpgBuilder.classesList;
  }
  
  public static List<Faction> getFactionsList()
  {
    return RpgBuilder.factionsList;
  }
  
  public static List<Item> getItemsList()
  {
    return RpgBuilder.itemsList;
  }

  public static String getItemRootMultiLangueName() {
    return itemRootMultiLangueName;
  }
  
  public static int getMinLevel()
  {
    return minLevel;
  }
  
  public static int getMaxLevel()
  {
    return maxLevel;
  }
  /**
   * Returns the Faction according to the name given in parameter.
   * @param selectedItem - The name of the faction look for.
   * @return The faction linked to this name.
   */
  public static Faction getFactionFromName(String factionName) {
    for(Faction faction: RpgBuilder.getFactionsList())
      if(faction.toString().equalsIgnoreCase(factionName))
        return faction;
    return null;
  }
  
  public static Faction getFactionFromId(String factionId) {
    for(Faction faction: RpgBuilder.getFactionsList())
      if(faction.getId().equalsIgnoreCase(factionId))
        return faction;
    return null;
  }
  
  public static Classe getClasseFromName(String classeName) {
    return getClasseFromNameRecursive(classeName, RpgBuilder.getClassesList());
  }
  
  private static Classe getClasseFromNameRecursive(String classeName,
                                                   List<Classe> subClassesList)
  {
    for(Classe classe: subClassesList)
    {
      if(classe.toString().equalsIgnoreCase(classeName))
        return classe;
      return getClasseFromNameRecursive(classeName, classe.getSubClassesList());
    }
    return null;
  }

  
  public static Classe getClasseFromId(String classeId) {
    return getClasseFromIdRecursive(classeId, RpgBuilder.getClassesList());
  }
  
  private static Classe getClasseFromIdRecursive(String classeId,
                                                   List<Classe> subClassesList)
  {
    for(Classe classe: subClassesList)
    {
      if(classe.getId().equalsIgnoreCase(classeId))
        return classe;
      return getClasseFromNameRecursive(classeId, classe.getSubClassesList());
    }
    return null;
  }
}